<?php

namespace app\api\logic;

use app\common\exception\BusinessException;
use app\common\model\AgentRelation;
use app\common\model\AppConfig;
use app\common\model\Course;
use app\common\model\MaterialFile;
use app\common\model\Order as OrderModel;
use app\common\model\UserCourse;
use app\common\model\UserMaterial;
use app\common\model\UserVideoCollection;
use app\common\model\UserVipCombo;
use app\common\service\GlobalsVariableService;
use app\common\service\UserService;
use app\pay\service\AliPayService;
use app\pay\service\WxCorpMcpPayService;
use app\pay\service\WxPayService;
use function app;

class Order
{
    /**
     * 创建订单
     * @param array $param
     * @return int
     * @throws BusinessException
     */
    public function create(array $param): int
    {
        // 提取参数
        $type = $param['type'];

        // 是否虚拟支付
        if (isIosVirtualPay()) {
            throw new BusinessException(config('mcp.ios_not_support_notice'));
        }

        // 根据类型创建订单
        $orderId = 0;
        switch ($type) {
            case 1:
                // 创建会员订单
                $orderId = $this->createVipOrder($param);
                break;
            case 2:
                // 创建课程订单
                $orderId = $this->createCourseOrder($param);
                break;
            case 3:
                // 创建资料订单
                $orderId = $this->createMaterialOrder($param);
                break;
            case 4:
                // 创建网课订单
                $orderId = $this->createVideoOrder($param);
                break;
        }

        // 返回
        return $orderId;
    }

    /**
     * 创建会员订单
     * @param array $param
     * @return mixed
     * @throws
     */
    public function createVipOrder(array $param)
    {
        // 提取参数
        $time = time();
        $userId = $param['userId'];
        $vip_comb_id = $param['vip_comb_id'] ?? 0;

        // 查询用户选择的专业
        $userInfo = (new UserService())->getUserById($userId, 'profession_id');
        if (!$userInfo) {
            throw new BusinessException('获取用户信息异常');
        }
        $profession_id = $userInfo['profession_id'];
        if (!$profession_id) {
            throw new BusinessException('未获取到您的专业信息');
        }

        // 查询套餐
        $vipCombInfo = app(UserVipCombo::class)->getInfoById($vip_comb_id);
        if (!$vipCombInfo) {
            throw new BusinessException('未获取套餐信息');
        }

        // 创建订单
        $agentRelationModel = new AgentRelation();
        $orderData = [
            'user_id' => $userId,
            'order_sn' => createOrderNo(),
            'order_type' => 1,
            'order_price' => $vipCombInfo['sale_price'],
            'status' => 1,
            'is_agent' => $agentRelationModel->hasParent($userId),
            'remark' => $vipCombInfo['name'],
            'extend' => json_encode(
                [
                    'vip_comb_id' => $vipCombInfo['id'],
                    'profession_id' => $userInfo['profession_id'],
                ]
            ),
            'a_time' => $time,
            'u_time' => $time,
        ];
        $orderId = app(OrderModel::class)->add_data($orderData);
        if (!$orderId) {
            throw new BusinessException('创建订单失败');
        }

        // 返回
        return $orderId;
    }

    /**
     * 创建课程订单
     * @param array $param
     * @return int
     * @throws BusinessException
     */
    public function createCourseOrder(array $param): int
    {
        // 提取参数
        $time = time();
        $userId = $param['userId'];
        $courseId = $param['course_id'] ?? 0;
        if (!$courseId) {
            throw new BusinessException('提交题库数据为空');
        }

        // 检查是否购买
        if (app(UserCourse::class)->checkHasCourse($userId, $courseId)) {
            throw new BusinessException('您已经购买过此题库');
        }

        // 查询课程信息
        $courseInfo = app(Course::class)->field('id,name,price')->find($courseId);
        if (!$courseInfo) {
            throw new BusinessException('题库数据异常');
        }
        if (!$courseInfo['price']) {
            throw new BusinessException('题库未设置价格');
        }
        if ($courseInfo['price'] <= 0) {
            throw new BusinessException('题库价格未设置正确');
        }

        // 创建订单
        $agentRelationModel = new AgentRelation();
        $order_data = [
            'user_id' => $userId,
            'order_sn' => createOrderNo(),
            'remark' => $courseInfo['name'],
            'order_type' => 2,
            'order_price' => $courseInfo['price'],
            'extend' => json_encode(
                [
                    'course_id' => $courseId,
                ]
            ),
            'status' => 1,
            'is_agent' => $agentRelationModel->hasParent($userId),
            'a_time' => $time,
            'u_time' => $time
        ];
        $orderId = app(OrderModel::class)->add_data($order_data);
        if (!$orderId) {
            throw new BusinessException('创建订单失败');
        }

        // 返回
        return $orderId;
    }

    /**
     * 创建资料订单
     * @param array $param
     * @return int
     * @throws BusinessException
     */
    public function createMaterialOrder(array $param): int
    {
        // 提取参数
        $time = time();
        $userId = $param['userId'];
        $material_id = $param['material_id'] ?? 0;
        if (!$material_id) {
            throw new BusinessException('提交数据为空');
        }

        // 检查是否购买
        $hasMaterial = (new UserMaterial())->getUserValidMaterial($userId, $material_id);
        if ($hasMaterial) {
            throw new BusinessException('您已经购买过此资料');
        }

        // 查询资料信息
        $materialInfo = app(MaterialFile::class)->find($material_id);
        if (!$materialInfo) {
            throw new BusinessException('资料数据异常');
        }
        if ($materialInfo['real_price'] <= 0) {
            throw new BusinessException('资料价格异常');
        }

        // 创建订单
        $agentRelationModel = new AgentRelation();
        $order_data = [
            'user_id' => $userId,
            'order_sn' => createOrderNo(),
            'remark' => $materialInfo['name'],
            'order_type' => 3,
            'order_price' => $materialInfo['real_price'],
            'extend' => json_encode(
                [
                    'material_id' => $material_id,
                ]
            ),
            'status' => 1,
            'is_agent' => $agentRelationModel->hasParent($userId),
            'a_time' => $time,
            'u_time' => $time
        ];
        $orderId = app(OrderModel::class)->add_data($order_data);
        if (!$orderId) {
            throw new BusinessException('创建订单失败');
        }

        // 返回
        return $orderId;
    }

    /**
     * 创建网课订单
     * @param array $param
     * @return int
     * @throws BusinessException
     */
    public function createVideoOrder(array $param): int
    {
        // 提取参数
        $time = time();
        $userId = $param['userId'];
        $collection_id = $param['collection_id'] ?? 0;
        if (!$collection_id) {
            throw new BusinessException('提交数据为空');
        }

        // 检查是否购买
        $hasVideo = app(UserVideoCollection::class)->getUserValidVideoCollection($userId, $collection_id);
        if ($hasVideo) {
            throw new BusinessException('您已经购买此网课');
        }

        // 查询合集信息
        $collectionVideoInfo = app(\app\common\model\VideoCollection::class)->find($collection_id);
        if (!$collectionVideoInfo) {
            throw new BusinessException('数据异常');
        }
        if ($collectionVideoInfo['price'] <= 0) {
            throw new BusinessException('价格异常');
        }

        // 创建订单
        $agentRelationModel = new AgentRelation();
        $order_data = [
            'user_id' => $userId,
            'order_sn' => createOrderNo(),
            'remark' => $collectionVideoInfo['name'],
            'order_type' => 4,
            'order_price' => $collectionVideoInfo['price'],
            'extend' => json_encode(
                [
                    'collection_id' => $collection_id,
                ]
            ),
            'status' => 1,
            'is_agent' => $agentRelationModel->hasParent($userId),
            'a_time' => $time,
            'u_time' => $time
        ];
        $orderId = app(OrderModel::class)->add_data($order_data);
        if (!$orderId) {
            throw new BusinessException('创建订单失败');
        }

        // 返回
        return $orderId;
    }

    /**
     * 查询订单信息
     * @param array $param
     * @return array
     * @throws
     */
    public function orderInfo(array $param): array
    {
        // 提取参数
        $id = $param['id'];

        // 查询订单信息
        $order = app(OrderModel::class)->find($id);
        if (!$order) {
            throw new BusinessException('订单信息不存在');
        }

        // 返回
        return [
            'orderInfo' => $order
        ];
    }

    /**
     * 订单支付
     * @param array $param
     * @return array
     * @throws
     */
    public function orderPay(array $param): array
    {
        // 提取参数
        $id = $param['id'];
        $userId = $param['userId'];
        $appId = GlobalsVariableService::get('appId');
        $appPlatform = GlobalsVariableService::get('appPlatform');
        $userInfo = (new UserService())->getUserById($userId);
        if (!$userInfo) {
            throw new BusinessException('用户信息不存在');
        }

        // 查询订单信息
        $order = app(OrderModel::class)->find($id);
        if (!$order || $order['status'] != 1) {
            throw new BusinessException('订单信息不存在或已支付');
        }

        // 获取租户全局支付配置
        $appConfigModel = new AppConfig();
        $globalPayConfig = $appConfigModel->getByIdAndType($appId, 'global_pay_config');
        if (!$globalPayConfig) {
            throw new BusinessException('租户未配置全局支付参数');
        }

        // 生成支付数据
        $payData = [];

        // 根据app环境唤起支付
        if ($appPlatform == 10) {

            // H5-支付宝支付
            $payUrl = app(AliPayService::class)->setAppId($appId)->buildPayData(
                $order['order_sn'],
                $order['order_price'],
                $order['remark'],
            );

            $payData = [
                'action' => 1,  // 跳转
                'payData' => [
                    'payUrl' => $payUrl
                ],
            ];

            // 普通H5环境
            return $payData;
        } elseif ($appPlatform == 11) {
            // 微信H5环境

            // 个人版
            if ($globalPayConfig['use_wx_h5_per_pay'] == 1) {
                $payUrl = app(WxPayService::class)->setAppId($appId)->buildCashierPayData(
                    $order['order_sn'],
                    $order['order_price'],
                    $order['remark']
                );
                $payData = [
                    'action' => 1,  // 跳转
                    'payData' => [
                        'payUrl' => $payUrl
                    ],
                ];
            } else {
                // 企业版
                throw new BusinessException('微信H5暂不支持企业版支付');
            }
        } elseif ($appPlatform == 20) {
            // 手机微信小程序
            if (!$userInfo['openid']) {
                throw new BusinessException('未绑定微信账号无法支付');
            }

            // 个人版
            if ($globalPayConfig['use_wx_mcp_per_pay'] == 1) {
                if ($globalPayConfig['use_wx_mcp_per_pay_type'] == 1) {
                    $payRes = app(WxPayService::class)->setAppId($appId)->buildPayData($order['order_sn'], $order['order_price'], $order['remark']);
                    $payData = [
                        'action' => 3,  // 个人小程序跳转支付
                        'payData' => $payRes, // 支付参数
                    ];
                } else {
                    $payRes = app(WxPayService::class)->setAppId($appId)->newBuildPayData(
                        $userInfo['openid'],
                        $order['order_sn'],
                        $order['order_price'],
                        $order['remark']
                    );
                    $payData = [
                        'action' => 4,  // 个人小程序原生支付
                        'payData' => $payRes, // 支付参数
                    ];
                }
            } else {
                $payData = $this->getCorpMcpPayData($appId, $userInfo, $order);
            }

        } elseif ($appPlatform == 21) {
            // 电脑微信小程序

            // 个人版
            if ($globalPayConfig['use_wx_mcp_per_pay'] == 1) {
                // 原生微信二维码支付|支持包一层二维码
                $payUrl = app(WxPayService::class)->setAppId($appId)->buildQrPayData(
                    $order['order_sn'],
                    $order['order_price'],
                    $order['remark'],
                    2
                );
                $payData = [
                    'action' => 2,  // 扫码
                    'payData' => [
                        'payUrl' => $payUrl
                    ]
                ];
            } else {
                $payData = $this->getCorpMcpPayData($appId, $userInfo, $order);
            }
        } elseif ($appPlatform == 30) {

            // H5-支付宝支付
            $payUrl = app(AliPayService::class)->setAppId($appId)->buildPayData(
                $order['order_sn'],
                $order['order_price'],
                $order['remark'],
            );

            $payData = [
                'action' => 5,  // 跳转
                'payData' => [
                    'payUrl' => $payUrl
                ],
            ];

            // 安卓和IOS
            return $payData;
        }

        // 返回
        return $payData;
    }

    /**
     * 获取企业小程序支付数据
     * @param $appId
     * @param $userInfo
     * @param $order
     * @return array
     * @throws BusinessException
     */
    private function getCorpMcpPayData($appId, $userInfo, $order): array
    {
        $payRes = app(WxCorpMcpPayService::class)->setAppId($appId)->buildPayData($userInfo['openid'], $order['order_sn'],
            $order['order_price'],
            $order['remark']);
        return [
            'action' => 4,  // 原生小程序支付
            'payData' => $payRes, // 支付参数
        ];
    }
}